﻿/*--------------------------------------------------------------------------------
 * Adaptive Intelligence - Windows Forms Controls Class Library
 * Version 2.00
 * 
 * Toolbox Close Button Class.
 *      Provides a close button UI element for a toolbox.
 *------------------------------------------------------------------------------*/

/*--------------------------------------------------------------------------------
 * System Imports
 *------------------------------------------------------------------------------*/
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace Adaptive.Foundation.Windows.Forms
{
    /// <summary>
    /// Provides a close button UI element for a toolbox.
    /// </summary>
    [ToolboxItem(false)]
    public partial class ToolboxCloseButton : AdaptiveControlBase
    {
        /*--------------------------------------------------------------------------------
         * Private Member Declarations
         *------------------------------------------------------------------------------*/
        #region Private Member Declarations
        /// <summary>
        /// Brush for background transparency.
        /// </summary>
        private SolidBrush _transparentBrush;
        /// <summary>
        /// Brush for background partial "highlight" opacity.
        /// </summary>
        private SolidBrush _clearBrush;
        /// <summary>
        /// Brush for background partial "mouse down" opacity.
        /// </summary>
        private SolidBrush _downBrush;
        /// <summary>
        /// Mosue entry flag.
        /// </summary>
        private bool _entered;
        /// <summary>
        /// Mouse down flag.
        /// </summary>
        private bool _mouseDown; 
        #endregion

        /*--------------------------------------------------------------------------------
         * Constructor / Dispose / Destructor Methods
         *------------------------------------------------------------------------------*/
        #region Constructor / Dispose / Destructor Methods
        /// <summary>
        /// Initializes a new instance of the class.
        /// </summary>
        /// <remarks>
        /// This is the default constructor.
        /// </remarks>
        public ToolboxCloseButton()
            : base()
        {
            InitializeComponent();

            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.ContainerControl, false);
            SetStyle(ControlStyles.Opaque, false);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            SetStyle(ControlStyles.ResizeRedraw, true);
            SetStyle(ControlStyles.Selectable, false);
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            SetStyle(ControlStyles.UserPaint, true);

            BackColor = Color.Transparent;
            ForeColor = SystemColors.ActiveCaptionText;

            _transparentBrush = new SolidBrush(Color.Transparent);
            _clearBrush = new SolidBrush(Color.FromArgb(160, 255, 255, 255));
            _downBrush = new SolidBrush(Color.FromArgb(160, 32, 
                            32, 32));

        }
        /// <summary>
        /// Deallocates internally allocated objects.
        /// </summary>
        /// <param name="disposing">
        /// A value indicating whether the object is being disposed.
        /// </param>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (_transparentBrush != null)
                    _transparentBrush.Dispose();

                if (_clearBrush != null)
                    _clearBrush.Dispose();

                if (components != null)
                    components.Dispose();
            }

            _transparentBrush = null;
            _clearBrush = null;
            components = null;
            base.Dispose(disposing);
        }
        #endregion

        /*--------------------------------------------------------------------------------
         * Protected Methods / Event Methods
         *------------------------------------------------------------------------------*/
        #region Protected Methods / Event Methods
        /// <summary>
        /// Handles the sizing of the control and raises the <see cref="E:System.Windows.Forms.Control.Resize"/>
        /// event.
        /// </summary>
        /// <param name="e">An <see cref="T:System.EventArgs"/> that contains the event data.</param>
        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            Height = 18;
            Width = 18;
        }
        /// <summary>
        /// Raises the <see cref="E:System.Windows.Forms.Control.MouseEnter"/> event.
        /// </summary>
        /// <param name="e">An <see cref="T:System.EventArgs"/> that contains the event data.</param>
        protected override void OnMouseEnter(EventArgs e)
        {
            base.OnMouseEnter(e);
            _entered = true;
            Invalidate();
        }
        /// <summary>
        /// Raises the <see cref="E:System.Windows.Forms.Control.MouseaDown"/> event.
        /// </summary>
        /// <param name="e">A <see cref="T:System.Windows.Forms.MouseEventArgs"/> that contains the event data.</param>
        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            _entered = true;
            _mouseDown = true;
            Invalidate();
        }
        /// <summary>
        /// Raises the <see cref="E:System.Windows.Forms.Control.MouseLeave"/> event.
        /// </summary>
        /// <param name="e">An <see cref="T:System.EventArgs"/> that contains the event data.</param>
        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);
            _entered = false;
            _mouseDown = false;
            Invalidate();
        }
        /// <summary>
        /// Raises the <see cref="E:System.Windows.Forms.Control.MouseUp"/> event.
        /// </summary>
        /// <param name="e">A <see cref="T:System.Windows.Forms.MouseEventArgs"/> that contains the event data.</param>
        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);
            _entered = true;
            _mouseDown = false;
            Invalidate();
        }
        /// <summary>
        /// Paints the background of the control.
        /// </summary>
        /// <param name="e">A <see cref="T:System.Windows.Forms.PaintEventArgs"/> that contains the event data.</param>
        protected override void OnPaintBackground(PaintEventArgs e)
        {
            base.OnPaintBackground(e);

            //Paint a "transparent" background.
            e.Graphics.FillRectangle(_transparentBrush, ClientRectangle);

            //Paint a "highligted" background.
            if (_mouseDown)
                e.Graphics.FillRectangle(_downBrush, ClientRectangle);
            else if (_entered)
                e.Graphics.FillRectangle(_clearBrush, ClientRectangle);

        }
        /// <summary>
        /// Raises the <see cref="E:System.Windows.Forms.Control.Paint"/> event.
        /// </summary>
        /// <param name="e">A <see cref="T:System.Windows.Forms.PaintEventArgs"/> that contains the event data.</param>
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            Pen p = new Pen(ForeColor);

            int x = 3;
            int y = 3;
            int ex = Width - 4;
            int ey = Height - 4;

            if (_mouseDown)
            {
                x++;
                y++; 
                ex++;
                ey++;
            }

            Pen borderPen = new Pen(SystemColors.ControlLight);

            e.Graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
            e.Graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
            e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

            e.Graphics.DrawArc(borderPen, new Rectangle(-2, -2, 4, 4), 0, 90);
            e.Graphics.DrawArc(borderPen, new Rectangle(16, -2, 4, 4), 90, 90);
            e.Graphics.DrawArc(borderPen, new Rectangle(16, 16, 4, 4), 180, 90);
            e.Graphics.DrawArc(borderPen, new Rectangle(-2, 16, 4, 4), 270, 90);

            e.Graphics.DrawLine(borderPen, new Point(2, 0), new Point(16, 0));
            e.Graphics.DrawLine(borderPen, new Point(0, 2), new Point(0, 16));
            e.Graphics.DrawLine(borderPen, new Point(2, 18), new Point(16, 18));
            e.Graphics.DrawLine(borderPen, new Point(18, 2), new Point(18, 16));

            e.Graphics.DrawLine(p, new Point(x, y), new Point(ex, ey));
            e.Graphics.DrawLine(p, new Point(x + 1, y), new Point(ex, ey - 1));
            e.Graphics.DrawLine(p, new Point(x, y + 1), new Point(ex - 1, ey));

            e.Graphics.DrawLine(p, new Point(ex, y), new Point(x, ey));
            e.Graphics.DrawLine(p, new Point(ex - 1, y), new Point(x, ey - 1));
            e.Graphics.DrawLine(p, new Point(ex, y + 1), new Point(x + 1, ey));

            p.Dispose();
        }
        #endregion
    }
}
